﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Darwin.Source.Components.World.Entities.MinionTypes
{
    class CResourceGatherer : CEntity
    {
        const float Height = 1.82f;
        const float MaxMoveSpeed = 10.0f;
        const float MinMoveSpeed = 5.0f;

        const float MaxCollectDistance = 2.0f;
        const float MaxDropOffDistance = 2.0f;

        const float MaxSpookDistance = 10.0f;

        private float m_fResourcesGathered;
        const float MaxResources = 10.0f;

        const float GatherRate = 500.0f;

        public CResourceGatherer()
        {
            m_fResourcesGathered = 0.0f;
        }

        public override bool Initialise( Team.CTeam myTeam )
        {
            return base.Initialise(myTeam);
        }

        public override void DoUpdate(Microsoft.Xna.Framework.GameTime gameTime, World w, List<PotentialFeild.CPotentialFeildVector> potentialFeildVectors, Vector4[] worldFeildData)
        {
            Vector3 v3Force = Vector3.Zero;

            float fClosestResource = float.MaxValue;
            float fResourceScale = (m_fResourcesGathered / MaxResources);
            float fGatherInclination = 1.0f - fResourceScale;
            float fTotalSpookScale = 0.0f;

            foreach (KeyValuePair<uint, CEntity> pair in w.m_entityDictionary)
            {
                if (pair.Value.teamSide != teamSide)
                {
                    Vector3 v3PointToMe = m_v3Position - pair.Value.Position;

                    if (v3PointToMe.LengthSquared() < MaxSpookDistance * MaxSpookDistance)
                    {
                        float fSpookScale = 1.0f - (v3PointToMe.LengthSquared() / (MaxSpookDistance * MaxSpookDistance));

                        fTotalSpookScale += fSpookScale;

                        v3Force = v3PointToMe * ( fSpookScale );
                    }
                }
            }

            fTotalSpookScale = Math.Min(fTotalSpookScale, 1.0f);
            fGatherInclination *= 1.0f - (fTotalSpookScale);

            foreach (PotentialFeild.CPotentialFeildVector pf in potentialFeildVectors)
            {
                float fDistance;

                if (pf.Power > 0.0f)
                {
                    if (pf.Type == Darwin.Source.Components.World.PotentialFeild.FeildType.Resources)
                    {
                        v3Force += (pf.GetForceAtPoint(ref m_v3Position, out fDistance)) * fGatherInclination;

                        fClosestResource = MathHelper.Min(fClosestResource, fDistance);

                        if (fDistance < MaxCollectDistance && m_fResourcesGathered < MaxResources)
                        {
                            m_fResourcesGathered += (GatherRate * ((float)gameTime.ElapsedGameTime.TotalSeconds))/100.0f;
                            pf.Power -= GatherRate * ((float)gameTime.ElapsedGameTime.TotalSeconds);
                            //pf.Power = MathHelper.Max(0.0f, pf.Power);
                        }
                    }
                    else if (pf.Type == Darwin.Source.Components.World.PotentialFeild.FeildType.Home)
                    {
                        v3Force += (pf.GetForceAtPoint(ref m_v3Position, out fDistance) * (1.0f - fGatherInclination));

                        if (fDistance < MaxDropOffDistance)
                        {
                            m_myTeam.CurrentResources += m_fResourcesGathered;
                            m_fResourcesGathered = 0.0f;
                        }
                    }
                }
            }

            if (v3Force.LengthSquared() > 0.001f)
            {
                v3Force = Vector3.Normalize(v3Force) * (MathHelper.Lerp(MinMoveSpeed, MaxMoveSpeed, (1.0f - fResourceScale)));
            }
            else
            {
                v3Force = Vector3.Zero;
            }

            m_v3Position += v3Force * ((float)gameTime.ElapsedGameTime.TotalSeconds);
        }

        public override void DoRender()
        {
#if DEBUG_GRAPHICS_ENABLED
            //
            //  Given a valid XZ value the terrain will return to you a height at that point, and the normal of the triangle you are on
            //
            Vector3 v3Normal;
            m_v3Position.Y = Singleton<SunXNA.Terrain.CTerrain>.Instance.GetHeightAtXZ(m_v3Position, out v3Normal);

            if (this.teamSide == Darwin.Source.Components.World.Team.Side.Darwin)
            {
                Singleton<SunXNA.DebugGraphics.CManager>.Instance.Add3DObject(m_UID,
                                                                              SunXNA.DebugGraphics.Type.Box,
                                                                              Color.GreenYellow,
                                                                              m_v3Position + (v3Normal * (Height * 0.5f)),
                                                                              v3Normal,
                                                                              new Vector3(0.7f, 0.7f, Height),
                                                                              1.0f);
            }
            else
            {
                Singleton<SunXNA.DebugGraphics.CManager>.Instance.Add3DObject(m_UID,
                                                                              SunXNA.DebugGraphics.Type.Box,
                                                                              Color.Blue,
                                                                              m_v3Position + (v3Normal * (Height * 0.5f)),
                                                                              v3Normal,
                                                                              new Vector3(0.7f, 0.7f, Height),
                                                                              1.0f);
            }
#endif
        }
    }
}
